#include "dataimporter.h"
#include <QFile>
#include <QTextStream>
#include <QSqlQuery>
#include <QSqlError>
#include <QJsonDocument>
#include <QJsonArray>
#include <QJsonObject>
#include <QXmlStreamReader>
#include <QFileInfo>
#include <QMessageBox>

DataImporter::DataImporter(QObject *parent)
    : QObject(parent)
{
}

bool DataImporter::importFile(const QString &filename, const QString &tableName, 
                              ImportFormat format, const QSqlDatabase &db)
{
    if (!db.isOpen()) {
        emit importError(tr("Database is not open"));
        return false;
    }
    
    if (tableName.isEmpty()) {
        emit importError(tr("Table name is empty"));
        return false;
    }
    
    bool result = false;
    switch (format) {
    case CSV:
        result = importFromCSV(filename, tableName, db);
        break;
    case JSON:
        result = importFromJSON(filename, tableName, db);
        break;
    case XML:
        result = importFromXML(filename, tableName, db);
        break;
    case SQL:
        result = importFromSQL(filename, tableName, db);
        break;
    default:
        emit importError(tr("Unsupported import format"));
        return false;
    }
    
    if (result) {
        emit importFinished(tr("Data imported successfully from %1 to table %2")
                           .arg(QFileInfo(filename).fileName()).arg(tableName));
    } else {
        emit importError(tr("Failed to import data from %1").arg(filename));
    }
    
    return result;
}

bool DataImporter::importFromCSV(const QString &filename, const QString &tableName, const QSqlDatabase &db)
{
    QFile file(filename);
    if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
        emit importError(tr("Cannot open file: %1").arg(filename));
        return false;
    }
    
    QTextStream in(&file);
    
    // 读取表头行
    if (in.atEnd()) {
        emit importError(tr("File is empty"));
        return false;
    }
    
    QString headerLine = in.readLine();
    QStringList headers = parseCSVLine(headerLine);
    
    if (headers.isEmpty()) {
        emit importError(tr("Invalid CSV format: empty header"));
        return false;
    }
    
    // 创建表（如果不存在）
    if (!createTableFromCSV(filename, tableName, db)) {
        emit importError(tr("Failed to create table"));
        return false;
    }
    
    // 准备插入语句
    QString placeholders;
    for (int i = 0; i < headers.size(); ++i) {
        if (i > 0) placeholders += ", ";
        placeholders += "?";
    }
    
    QString insertSQL = QString("INSERT INTO %1 VALUES (%2)").arg(tableName, placeholders);
    QSqlQuery query(db);
    query.prepare(insertSQL);
    
    // 读取数据行
    int rowCount = 0;
    while (!in.atEnd()) {
        QString line = in.readLine();
        if (line.trimmed().isEmpty()) {
            continue;
        }
        
        QStringList values = parseCSVLine(line);
        
        // 确保值的数量与列数匹配
        while (values.size() < headers.size()) {
            values.append(QString());
        }
        
        // 绑定值
        query.clear();
        query.prepare(insertSQL);
        for (int i = 0; i < headers.size() && i < values.size(); ++i) {
            QString value = unescapeCSVField(values.at(i));
            if (value == "[NULL]") {
                query.addBindValue(QVariant());
            } else {
                query.addBindValue(value);
            }
        }
        
        if (!query.exec()) {
            emit importError(tr("Failed to insert row: %1").arg(query.lastError().text()));
            return false;
        }
        
        rowCount++;
        if (rowCount % 100 == 0) {
            emit importProgress(rowCount); // 这里应该有一个最大值来计算百分比
        }
    }
    
    file.close();
    return true;
}

bool DataImporter::importFromJSON(const QString &filename, const QString &tableName, const QSqlDatabase &db)
{
    QFile file(filename);
    if (!file.open(QIODevice::ReadOnly)) {
        emit importError(tr("Cannot open file: %1").arg(filename));
        return false;
    }
    
    QByteArray data = file.readAll();
    file.close();
    
    QJsonParseError parseError;
    QJsonDocument doc = QJsonDocument::fromJson(data, &parseError);
    if (parseError.error != QJsonParseError::NoError) {
        emit importError(tr("Failed to parse JSON: %1").arg(parseError.errorString()));
        return false;
    }
    
    if (!doc.isArray()) {
        emit importError(tr("JSON root element must be an array"));
        return false;
    }
    
    QJsonArray jsonArray = doc.array();
    if (jsonArray.isEmpty()) {
        emit importError(tr("JSON array is empty"));
        return false;
    }
    
    // 创建表（如果不存在）
    if (!createTableFromJSON(filename, tableName, db)) {
        emit importError(tr("Failed to create table"));
        return false;
    }
    
    // 获取列名
    QJsonObject firstObj = jsonArray.first().toObject();
    QStringList columns;
    for (auto it = firstObj.begin(); it != firstObj.end(); ++it) {
        columns.append(it.key());
    }
    
    // 准备插入语句
    QString placeholders;
    for (int i = 0; i < columns.size(); ++i) {
        if (i > 0) placeholders += ", ";
        placeholders += "?";
    }
    
    QString insertSQL = QString("INSERT INTO %1 VALUES (%2)").arg(tableName, placeholders);
    QSqlQuery query(db);
    
    // 插入数据
    for (int i = 0; i < jsonArray.size(); ++i) {
        QJsonObject obj = jsonArray.at(i).toObject();
        
        query.clear();
        query.prepare(insertSQL);
        for (const QString &column : columns) {
            QJsonValue value = obj.value(column);
            if (value.isUndefined() || value.isNull()) {
                query.addBindValue(QVariant());
            } else {
                query.addBindValue(value.toVariant());
            }
        }
        
        if (!query.exec()) {
            emit importError(tr("Failed to insert row: %1").arg(query.lastError().text()));
            return false;
        }
        
        if (i % 100 == 0) {
            emit importProgress(i * 100 / jsonArray.size());
        }
    }
    
    return true;
}

bool DataImporter::importFromXML(const QString &filename, const QString &tableName, const QSqlDatabase &db)
{
    QFile file(filename);
    if (!file.open(QIODevice::ReadOnly)) {
        emit importError(tr("Cannot open file: %1").arg(filename));
        return false;
    }
    
    QXmlStreamReader xml(&file);
    
    // 查找根元素
    while (!xml.atEnd() && xml.readNextStartElement()) {
        if (xml.name() == "table") {
            break;
        }
    }
    
    if (xml.hasError()) {
        emit importError(tr("Failed to parse XML: %1").arg(xml.errorString()));
        return false;
    }
    
    if (xml.atEnd()) {
        emit importError(tr("Invalid XML format: missing table element"));
        return false;
    }
    
    // 读取第一行以获取列信息
    QStringList columns;
    QList<QVariantList> rowData;
    
    while (!xml.atEnd() && xml.readNextStartElement()) {
        if (xml.name() == "row") {
            QVariantList row;
            QStringList currentColumns;
            
            while (!xml.atEnd() && xml.readNextStartElement()) {
                QString columnName = xml.name().toString();
                QString columnValue = xml.readElementText();
                
                // 记录列名
                if (!columns.contains(columnName)) {
                    columns.append(columnName);
                }
                currentColumns.append(columnName);
                
                // 添加值
                row.append(columnValue);
            }
            
            // 确保行数据与列对齐
            QVariantList alignedRow;
            for (const QString &col : columns) {
                int index = currentColumns.indexOf(col);
                if (index >= 0) {
                    alignedRow.append(row.at(index));
                } else {
                    alignedRow.append(QVariant());
                }
            }
            
            rowData.append(alignedRow);
        } else {
            xml.skipCurrentElement();
        }
    }
    
    if (xml.hasError()) {
        emit importError(tr("Failed to parse XML: %1").arg(xml.errorString()));
        return false;
    }
    
    file.close();
    
    if (rowData.isEmpty()) {
        emit importError(tr("No data found in XML file"));
        return false;
    }
    
    // 创建表
    QSqlQuery query(db);
    QString createSQL = QString("CREATE TABLE IF NOT EXISTS %1 (").arg(tableName);
    for (int i = 0; i < columns.size(); ++i) {
        if (i > 0) createSQL += ", ";
        createSQL += QString("\"%1\" TEXT").arg(columns.at(i));  // 简化处理，所有列都设为TEXT类型
    }
    createSQL += ")";
    
    if (!query.exec(createSQL)) {
        emit importError(tr("Failed to create table: %1").arg(query.lastError().text()));
        return false;
    }
    
    // 准备插入语句
    QString placeholders;
    for (int i = 0; i < columns.size(); ++i) {
        if (i > 0) placeholders += ", ";
        placeholders += "?";
    }
    
    QString insertSQL = QString("INSERT INTO %1 VALUES (%2)").arg(tableName, placeholders);
    
    // 插入数据
    for (int i = 0; i < rowData.size(); ++i) {
        query.clear();
        query.prepare(insertSQL);
        for (const QVariant &value : rowData.at(i)) {
            query.addBindValue(value);
        }
        
        if (!query.exec()) {
            emit importError(tr("Failed to insert row: %1").arg(query.lastError().text()));
            return false;
        }
        
        if (i % 100 == 0) {
            emit importProgress(i * 100 / rowData.size());
        }
    }
    
    return true;
}

bool DataImporter::importFromSQL(const QString &filename, const QString &tableName, const QSqlDatabase &db)
{
    Q_UNUSED(tableName)
    
    QFile file(filename);
    if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
        emit importError(tr("Cannot open file: %1").arg(filename));
        return false;
    }
    
    QTextStream in(&file);
    QString sqlContent = in.readAll();
    file.close();
    
    // 分割SQL语句（简单实现，按分号分割）
    QStringList statements = sqlContent.split(';', Qt::SkipEmptyParts);
    
    QSqlQuery query(db);
    for (int i = 0; i < statements.size(); ++i) {
        QString statement = statements.at(i).trimmed();
        if (statement.isEmpty()) {
            continue;
        }
        
        if (!query.exec(statement)) {
            emit importError(tr("Failed to execute SQL statement: %1\nError: %2")
                            .arg(statement).arg(query.lastError().text()));
            return false;
        }
        
        emit importProgress((i + 1) * 100 / statements.size());
    }
    
    return true;
}

QStringList DataImporter::parseCSVLine(const QString &line) const
{
    QStringList fields;
    QString field;
    bool inQuotes = false;
    
    for (int i = 0; i < line.length(); ++i) {
        QChar ch = line.at(i);
        
        if (ch == '"') {
            if (inQuotes && i + 1 < line.length() && line.at(i + 1) == '"') {
                // 双引号转义
                field += '"';
                i++; // 跳过下一个引号
            } else {
                // 切换引号状态
                inQuotes = !inQuotes;
            }
        } else if (ch == ',' && !inQuotes) {
            // 字段分隔符
            fields.append(field);
            field.clear();
        } else {
            field += ch;
        }
    }
    
    fields.append(field); // 添加最后一个字段
    return fields;
}

QString DataImporter::unescapeCSVField(const QString &field) const
{
    QString result = field;
    if (result.startsWith('"') && result.endsWith('"')) {
        result = result.mid(1, result.length() - 2);
        result.replace("\"\"", "\"");
    }
    return result;
}

bool DataImporter::createTableFromCSV(const QString &filename, const QString &tableName, const QSqlDatabase &db)
{
    Q_UNUSED(filename)
    
    // 对于CSV导入，我们假设表已经存在，或者让用户手动创建表
    // 这里简单检查表是否存在
    QStringList tables = db.tables();
    if (tables.contains(tableName, Qt::CaseInsensitive)) {
        return true;
    }
    
    // 表不存在，我们无法自动创建，因为不知道列的数据类型
    emit importError(tr("Table '%1' does not exist. Please create the table first.").arg(tableName));
    return false;
}

bool DataImporter::createTableFromJSON(const QString &filename, const QString &tableName, const QSqlDatabase &db)
{
    Q_UNUSED(filename)
    
    // 对于JSON导入，我们假设表已经存在，或者让用户手动创建表
    // 这里简单检查表是否存在
    QStringList tables = db.tables();
    if (tables.contains(tableName, Qt::CaseInsensitive)) {
        return true;
    }
    
    // 表不存在，我们无法自动创建，因为不知道列的数据类型
    emit importError(tr("Table '%1' does not exist. Please create the table first.").arg(tableName));
    return false;
}